/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package db.definitions;

import java.util.ArrayList;
import java.util.Iterator;

/**
 *
 * @author abracadabuda
 */
public class DatabaseDefinition extends AbstractDefinition {

    public static final int SQL_FIRST = 1;
    public static final int TABLE = 3;
    public static final int VIEW = 5;
    public static final int FUNCTION = 2;
    public static final int TRIGGER = 7;
    public static final int RULE = 6;
    public static final int REFERENCE = 4;
    public static final int SCRIPT = 1;
    public static final int SQL_LAST = 7;
    
    private String name;
    private ArrayList<TableDefinition> tables = new ArrayList<TableDefinition>();
    private ArrayList<ViewDefinition> views = new ArrayList<ViewDefinition>();
    private ArrayList<RuleDefinition> rules = new ArrayList<RuleDefinition>();
    private ArrayList<String> scripts = new ArrayList<String>();
    private ArrayList<TriggerDefinition> triggers = new ArrayList<TriggerDefinition>();
    private ArrayList<FunctionDefinition> functions = new ArrayList<FunctionDefinition>();

    /**
     * creates the database with given prefix (used for schema name)
     * @param prefix used for schema name
     */
    public DatabaseDefinition(String prefix) {
        AbstractDefinition.prefix = prefix;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public ArrayList<TableDefinition> getTables() {
        return tables;
    }

    /**
     * adds Table into tableList
     * @param table table to be added
     */
    public void addTable(TableDefinition table) {
        tables.add(table);
    }

    /**
     * adds view into viewList
     * @param view view to be added
     */
    public void addView(ViewDefinition view) {
        views.add(view);
    }

    /**
     * adds rule to rulesList
     * @param rule rule to be added
     */
    public void addRule(RuleDefinition rule) {
        rules.add(rule);
    }

    /**
     * add script to scriptList
     * @param script script to be added
     */
    public void addScript(String script) {
        scripts.add(script.replaceAll("%%%", "\"" + prefix + "\""));
    }

    /**
     * add trigger to the triggerList
     * @param trigger trigger to be added
     */
    public void addTrigger(TriggerDefinition trigger) {
        triggers.add(trigger);
    }

    /**
     * adds function to functionList
     * @param function function to be added
     */
    public void addFunction(FunctionDefinition function) {
        functions.add(function);
    }

    /**
     * get the dump of database (for testing)
     */
    public void getDump() {
        System.out.println("Database");
        System.out.println("Name: " + name);
        System.out.println("Prefix: " + prefix);
        for (Iterator i = tables.iterator(); i.hasNext();) {
            TableDefinition table = (TableDefinition) i.next();
            if (table.getName().equals("property_tags")) {
                table.getDump();
            }
        }
    }

    /**
     * gets the SQL code of database creation (including all tables, views, rules, functions, scripts, indexes...)
     * @return SQL code
     */
    public String getSQL() {
        String sql = "";

        sql += "\n\n\n-------------------- INIT SCRIPTS\n\n\n";
        for (String script : scripts) {
            sql += script + "\n\n";
        }

        sql += "\n\n\n-------------------- CREATING FUNCTIONS\n\n\n";
        for (FunctionDefinition function : functions) {
            sql += function.getSQL() + "\n";
        }

        sql += "\n\n\n-------------------- CREATING TABLES\n\n\n";
        for (TableDefinition table : tables) {
            if (!table.getSQL().equals("")) {
                sql += table.getSQL();
            }
            if (!table.getCommentSQL().equals("")) {
                sql += table.getCommentSQL();
            }
            if (!table.getColumnsCommentsSQL().equals("")) {
                sql += table.getColumnsCommentsSQL();
            }
            if (!table.getIndexesSQL().equals("")) {
                sql += table.getIndexesSQL();
            }
            sql += "\n";
        }

        sql += "\n\n\n-------------------- CREATING REFERENCES\n\n\n";
        for (TableDefinition table : tables) {
            if (!table.getReferencesSQL().equals("")) {
                sql += table.getReferencesSQL() + "\n";
            }
        }

        sql += "\n\n\n--------------------  CREATING VIEWS\n\n\n";
        for (ViewDefinition view : views) {
            sql += view.getSQL() + "\n";
        }

        sql += "\n\n\n--------------------  CREATING RULES\n\n\n";
        for (RuleDefinition rule : rules) {
            sql += rule.getSQL() + "\n";
        }

        sql += "\n\n\n--------------------  CREATING TRIGGERS\n\n\n";
        for (TriggerDefinition triggerDefintion : triggers) {
            sql += triggerDefintion.getSQL() + "\n";
        }

        return sql;
    }

    /**
     * gets the SQL code of database creation of given type(including all tables, views, rules, functions, scripts, indexes...)
     * @param type type of database DDL
     * @return SQL code
     */
    public String getSQL(int type) {
        String sql = "";

        switch (type) {
            case SCRIPT:
                sql += "\n\n\n-------------------- INIT SCRIPTS\n\n\n";
                for (String script : scripts) {
                    sql += script + "\n\n";
                }
                break;
            case FUNCTION:
                sql += "\n\n\n-------------------- CREATING FUNCTIONS\n\n\n";
                for (FunctionDefinition function : functions) {
                    sql += function.getSQL() + "\n";
                }
                break;
            case TABLE:
                sql += "\n\n\n-------------------- CREATING TABLES\n\n\n";
                for (TableDefinition table : tables) {
                    if (!table.getSQL().equals("")) {
                        sql += table.getSQL();
                    }
                    if (!table.getCommentSQL().equals("")) {
                        sql += table.getCommentSQL();
                    }
                    if (!table.getColumnsCommentsSQL().equals("")) {
                        sql += table.getColumnsCommentsSQL();
                    }
                    if (!table.getIndexesSQL().equals("")) {
                        sql += table.getIndexesSQL();
                    }
                    sql += "\n";
                }
                break;
            case REFERENCE:
                sql += "\n\n\n-------------------- CREATING REFERENCES\n\n\n";
                for (TableDefinition table : tables) {
                    if (!table.getReferencesSQL().equals("")) {
                        sql += table.getReferencesSQL() + "\n";
                    }
                }
                break;
            case VIEW:
                sql += "\n\n\n--------------------  CREATING VIEWS\n\n\n";
                for (ViewDefinition view : views) {
                    sql += view.getSQL() + "\n";
                }
                break;
            case RULE:
                sql += "\n\n\n--------------------  CREATING RULES\n\n\n";
                for (RuleDefinition rule : rules) {
                    sql += rule.getSQL() + "\n";
                }
                break;
            case TRIGGER:
                sql += "\n\n\n--------------------  CREATING TRIGGERs\n\n\n";
                for (TriggerDefinition triggerDefintion : triggers) {
                    sql += triggerDefintion.getSQL() + "\n";
                }
                break;
        }
        return sql;
    }

    /**
     * gets the name of type of database DDL operation
     * @param type type of database DDL operation
     * @return string value of type
     */
    public static String getNameOfType(int type) {
        String str = "";
        switch (type) {
            case SCRIPT:
                str = "Running intitial scripts";
                break;
            case FUNCTION:
                str = "Creating functions";
                break;
            case TABLE:
                str = "Creating tables";
                break;
            case REFERENCE:
                str = "Creating references";
                break;
            case VIEW:
                str = "Creating views";
                break;
            case RULE:
                str = "Creating rules";
                break;
            case TRIGGER:
                str = "Creating triggers";
                break;
        }
        return str;
    }

    public ArrayList<ViewDefinition> getViews() {
        return views;
    }

    public void setViews(ArrayList<ViewDefinition> views) {
        this.views = views;
    }

    public ArrayList<String> getScripts() {
        return scripts;
    }

    public void setScripts(ArrayList<String> scripts) {
        this.scripts = scripts;
    }

    public ArrayList<TriggerDefinition> getTriggers() {
        return triggers;
    }

    public void setTriggers(ArrayList<TriggerDefinition> triggers) {
        this.triggers = triggers;
    }

    public ArrayList<FunctionDefinition> getFunctions() {
        return functions;
    }

    public void setFunctions(ArrayList<FunctionDefinition> functions) {
        this.functions = functions;
    }
}
